home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / h / arith.h < prev    next >
C/C++ Source or Header  |  1991-03-19  |  6KB  |  266 lines

  1. #ifndef lsub
  2. #ifdef AIX3
  3. #define ulong ulong_
  4. #endif
  5. typedef unsigned long ulong;
  6. ulong overflow, hiremainder;
  7. #endif
  8.  
  9. #ifndef WSIZ
  10. #define WSIZ 32
  11.  
  12.  
  13. /*  Notation: if A and B are unsigned 32 bit integers,
  14.     1)  A:B signifies the 64 bit integer A*2^32 + B
  15.     2)  S(A:B) the signed 64 bit integer
  16.     3)  I(x) is a true integer.   If (x) were unsigned then
  17.         I(x) >= 0, otherwise I(x) has the same sign and size as x. 
  18.  
  19.   */
  20.  
  21. /* TEMPVARS are variables are used to prevent double evaluation
  22.   of arguments in macros, and also to make sure of the type.
  23.   Be careful about the composition of macros
  24. */
  25.  
  26. #define TEMPVARS ulong Xtx,Xty,Xtres;
  27.  
  28. /*
  29.   ulong res,x,y; res = addll(x,y);
  30.         then
  31.    I(overflow:res) == I(x) + I(y);
  32. */   
  33.  
  34. #define addll(x,y) \
  35.        (Xtx=(x),Xty=(y), Xtres = Xtx+Xty, \
  36.          overflow = \
  37.          (Xtres < Xtx ? 1:0), Xtres)
  38.  
  39. /*
  40.    ulong res,x,y; o = overflow; res = addllx(x,y);
  41.             then
  42.    I(overflow:res) == I(x) + I(y) +I(o).
  43. */
  44.  
  45. #ifndef addllx
  46. #define addllx(x,y) \
  47.   (Xtx=(x),Xtres= Xtx + (y), \
  48.    (Xtres < Xtx ? (Xtres += overflow ,overflow=1,Xtres) : \
  49.     (  Xtres += overflow , \
  50.      overflow = (Xtres < overflow ? 1 : 0), \
  51.      Xtres)))
  52. #endif
  53.  
  54.  /* ulong x,y,w,o;
  55.     if we do  o = overflow, res = subll(x,y) then
  56.      I(S(-overflow:res))  == I(x) -I(y);
  57.    */
  58. #ifndef subll
  59. #define subll(x,y) \
  60.   (Xtx=(x),Xty=(y),Xtres= Xtx - Xty, \
  61.      overflow = (Xtx >= Xty ? 0 : 1), Xtres)
  62. #endif
  63.  
  64. /*  ulong x,y,o,res; o = overflow; res= subllx(x,y);
  65.            then
  66.       I(S(-overflow):res) == I(x) - I(y) -I(o) 
  67.     where overflow is in {0,1} at all times.
  68. */
  69.  
  70. #ifndef subblx
  71. #define subllx(x,y) \
  72.   (Xtx=(x),Xty=(y),Xtres= Xtx - Xty, Xtres -=overflow, \
  73.    (Xty > Xtx ?  overflow = 1 : \
  74.     Xty < Xtx ?  overflow = 0 : 0), \
  75.    Xtres)
  76. #endif
  77.  
  78. #define shiftlr(x,y) \
  79.        (Xtx = x,  hiremainder=Xtx<<(32-y),Xtx>>y)
  80.  
  81. #define shiftl(x,y) \
  82.        (Xtx = x,  hiremainder=Xtx>>(32-y),Xtx<<y)
  83.  
  84.  
  85. #define llsub(h1,l1,h,l) \
  86. do{int tem= (int)l - (int) l1; \
  87.      if((UINT)l1> (UINT) l) (UINT) h--; \
  88.    l= (int)l - (int) l1; \
  89.    h=h-h1;\
  90. } while (0) 
  91.  
  92. /* x is less than WSIZ and it is shifted n bits into hi and lo */
  93.  
  94. #define llshift(x,n,hi,lo) \
  95. do { hi = x >> (WSIZ - n) ; \
  96.      lo = x << n ; \
  97.   }while (0)
  98.  
  99. #define UINT unsigned int
  100.  
  101.  
  102.     
  103. #define lladd(h1,l1,h,l) \
  104. do {UINT res; res=(UINT)l1+(UINT)l; \
  105.  if ((UINT)res< (UINT)l1 || (UINT)res< (UINT)l) \
  106.    /* overflow */ \
  107.    (h)++;  \
  108.      l=res; \
  109.     h= (UINT)h+(UINT)h1; \
  110. }while (0)
  111.  
  112.  
  113.    /* x,y unsigned longs.
  114.      u = x + y  if (u > 2^32)  h = h+1; */
  115. #ifndef add_carry
  116. #define add_carry(x,y,h) \
  117.   (Xtx = (x), Xtres = Xtx +(y), (Xtres < Xtx ? (h++,1):0), Xtres)
  118. #endif
  119. #endif
  120.  
  121. #ifndef BASE_COUNTER 
  122. #define BASE_COUNTER 0
  123. #endif
  124.  
  125.  
  126. #define divll(x,y) divul(x,y,hiremainder)
  127.  
  128. /*  ulong x,y,h, res; hi = rem;  res = divul(x,y,rem)
  129.            then
  130.     I(hi:x) ==  I(y) * I(res) + I(rem)
  131.         and  ( 0 = < rem < y)
  132. */
  133.  
  134. #ifndef divul
  135. #define divul(x,y,h) divul3(x,y,&h)
  136. #endif
  137.  
  138. /*  ulong x,y,h, res; res = mulul(x,y,h)
  139.            then
  140.     I(h:res) ==  I(x) * I(y);
  141. */
  142. #ifndef mulul
  143. #define mulul(x,y,h) mulul3(x,y,&h)
  144. #endif
  145.  
  146. #ifndef addmul
  147. #define addmul(x,y) \
  148.   (Xtx = hiremainder, Xtres = mulul(x,y,hiremainder),\
  149.    add_carry(Xtx,Xtres,hiremainder))
  150. #endif
  151.  
  152. #ifdef SET_MACHINE_CARRY
  153.              
  154. #define ADDLLX(x,y,z) \
  155.   SET_MACHINE_CARRY(overflow); \
  156.   (z) = ADDXCC((x),(y)); \
  157.   SET_OVERFLOW
  158.  
  159. #define SUBLLX(x,y,z) \
  160.   SET_MACHINE_CARRY(overflow); \
  161.   (z) = SUBXCC((x),(y)); \
  162.   SET_OVERFLOW
  163.  
  164.  
  165. #ifdef C_SWITCH_DOESNT_AFFECT_CARRY
  166.  
  167. #define CASE(i,op) case i: MP_NEXT_UP(zp) = op(MP_NEXT_UP(xp),(MP_NEXT_UP(yp)))
  168.  
  169. #define QUICK_LOOP(j,op) \
  170.   do{SET_MACHINE_CARRY(overflow); \
  171.   switch(j){ \
  172.   default:  \
  173.     CASE(16,op); \
  174.     CASE(15,op); \
  175.     CASE(14,op); \
  176.     CASE(13,op); \
  177.     CASE(12,op); \
  178.     CASE(11,op); \
  179.     CASE(10,op); \
  180.     CASE(9,op); \
  181.     CASE(8,op); \
  182.     CASE(7,op); \
  183.     CASE(6,op); \
  184.     CASE(5,op); \
  185.     CASE(4,op); \
  186.     CASE(3,op); \
  187.     CASE(2,op); \
  188.     CASE(1,op); \
  189.   case 0: SET_OVERFLOW; j -= 16;}} while (j > 0)
  190.  
  191. #else
  192. /* The C switch statement changes the machine carry, so
  193.    that we must reset it each time we enter */
  194.   
  195. #define LA(i,op)  L ## op ## i:  MP_NEXT_UP(zp) = \
  196.   op(MP_NEXT_UP(xp),MP_NEXT_UP(yp))
  197. #define CA(i,op) case i: SET_MACHINE_CARRY(overflow);\
  198.   goto L ## op ## i
  199. #define QUICK_LOOP(j,op) \
  200.  do {switch (j) { default: \
  201.  CA(16,op);CA(15,op);CA(14,op);CA(13,op);CA(12,op);CA(11,op);CA(10,op); \
  202.  CA(9,op);CA(8,op);CA(7,op);CA(6,op);CA(5,op);CA(4,op);CA(3,op); \
  203.  CA(2,op);CA(1,op); \
  204.  LA(16,op);LA(15,op);LA(14,op);LA(13,op);LA(12,op);LA(11,op);LA(10,op); \
  205.  LA(9,op);LA(8,op);LA(7,op);LA(6,op);LA(5,op);LA(4,op);LA(3,op);LA(2,op);\
  206.  LA(1,op); \
  207.  SET_OVERFLOW; j -= 16;}} while (j > 0)
  208.  
  209.  /* end  else C_SWITCH_DOESNT_AFFECT_CARRY */
  210. #endif 
  211.  
  212.     /* endif don't use machine carry in separate ops */
  213. #endif             
  214.  
  215.              
  216. #ifndef ADDLLX
  217. #define ADDLLX(x,y,z) (z) = addllx((x),(y))
  218. #endif
  219. /* z=x-y-overflow */
  220. #ifndef SUBLLX
  221. #define SUBLLX(x,y,z) (z) = subllx((x),(y))
  222. #endif
  223.  
  224. #ifndef mulll
  225. #define mulll(x,y) mulul(x,y,hiremainder)
  226. #endif
  227.  
  228. #ifndef mulul
  229. #define mulul(a,b,h) mulul3(a,b,&h)
  230. #endif
  231.  
  232. /*  The following macros are for stepping through
  233.     a bignum , after positioning a pointer at the
  234.     high or low word.
  235. */    
  236.  
  237. #define MP_START_LOW(u,x,l)  u = (x)+l
  238. #define MP_START_HIGH(u,x,l)  u = (x)+2
  239. #define MP_NEXT_UP(u) (*(--(u)))
  240. #define MP_NEXT_DOWN(u) (*((u)++))
  241.   /* ith word from the least significant */
  242. #define MP_ITH_WORD(u,i,l) (u)[l-i-1]
  243. #define MP_CODE_WORDS 2
  244. /* MP_LOW(x,lgef(x)) is the least significant  word */
  245. #define MP_LOW(x,l) ((x)[(l)-1])
  246. /* most significant word if l is the lgef(x) */  
  247. #define MP_HIGH(x,l) (x)[2]
  248.  
  249.   /*Some machines will iterate more efficiently with different bottoms
  250. for the iteration.  Eg with gcc and mc68k one can generate the dbra
  251. instruction which is done when i == -1.  The dbra does not alter the
  252. condition code which can be important in a tight loop.  */
  253.  
  254. #define MP_COUNT_LG(l)  COUNT(l - MP_CODE_WORDS )
  255.   /* i should be the number of counts so if i = COUNT(3)
  256.      WHILE_COUNT(--i) will repeat body 3 times. */
  257. #define  COUNT(l) (l +1+BASE_COUNTER)
  258. #define WHILE_COUNT(l) while (l!=BASE_COUNTER)
  259.  
  260. extern ulong ABS_MOST_NEGS[];
  261. extern ulong MOST_NEGS[];
  262.  
  263.  
  264.  
  265.      
  266.